package com.sff.webservice.data {
	
	public class WSResponder {
		
		private var objData:Object;
		
		public function WSResponder(xml:XML, operations:WSOperations) {
			
			parseResponse(xml, operations);
		}
		
		private function parseResponse(xmlResponse:XML, wsOperations:WSOperations):void {
			
			var soapNS:Namespace = xmlResponse.namespace();
			var defaultNS:Namespace = new Namespace(wsOperations.targetNameSpace);
			
			var xmlBody:XMLList = xmlResponse.soapNS::Body.children();
			
			var responseName:String = xmlBody[0].localName();
			
			if(wsOperations.isPortType()) {			
				objData = parsePortType(xmlBody.result);	
			}
			
			else {
				var methodName:String = responseName.split("Response")[0];			
				
				var wsMethod:WSMethod = wsOperations.getResponseObject(responseName);
				
				var xmlResult:XMLList = xmlBody.defaultNS::[methodName + "Result"].children();
			
				objData = parseXMLList(xmlResult, wsMethod, wsOperations);			
			}
		}
		
		
		private function parseXMLList(xmlResult:XMLList, wsMethod:WSMethod, wsOperations:WSOperations): Object {	
			
			var tmp:Array;
			
			//one argument
			if(wsMethod.arguments.length == 1) {
				
				var wsArgument:WSArgument = wsMethod.arguments[0];
				
				// OR 1 ITEM OR REFERENCE
				if(wsArgument.isReference()) {
					
					// TNS
					if(wsArgument.isArray()) { 
						
						// ARRAY OF TNS OBJECT
						wsMethod = wsOperations.getComplexObject(wsArgument.type);
						
						tmp = new Array();						
						for(var i:int = 0; i < xmlResult.length(); i++) {
							tmp.push(parseXMLList(xmlResult[i].children(), wsMethod, wsOperations));
						}
						
						return tmp;
					}
					
					else {
						wsMethod = wsOperations.getComplexObject(wsArgument.type);						
						return parseXMLList(xmlResult, wsMethod, wsOperations);
					}
				}
				
				
				else {
					if(xmlResult.children().length() == 0) {
						
						if (xmlResult[0] == undefined) {							
							return null;
						} else {
							return parsePortType(xmlResult[0]);
						}
					}
					
					else {
						
						wsMethod = wsOperations.getComplexObject(wsArgument.type);
						
						tmp = new Array();						
						for(i = 0; i < xmlResult.children().length(); i++) {
							tmp.push(xmlResult.children()[i]);
						}
						
						return tmp;
					}
				}
			}
			
			
			//multi arguments
			else {
				
				var obj:Object = new Object();				
				
				var tmpWSArgument:WSArgument;
				var tmpWSMethod:WSMethod;
				
				tmp = new Array();
				
				// MEERDERE PROPS
				for(i = 0; i < xmlResult.length(); i++) {
					
					tmpWSArgument = wsOperations.getComplexObjectArgument(wsMethod.arguments, xmlResult[i].localName());
					
					if(tmpWSArgument == null) {
						tmp.push(parseXMLList(xmlResult[i].children(), wsMethod, wsOperations));	
					}
					
					else if(xmlResult[i].children().length() > 1 || tmpWSArgument.isArray()) {
						tmpWSMethod = wsOperations.getComplexObject(tmpWSArgument.type);						
						
						obj[tmpWSArgument.name] = new Array();
						obj[tmpWSArgument.name] = parseXMLList(xmlResult[i].children(), tmpWSMethod, wsOperations);
					}					
					
					else {
						obj[tmpWSArgument.name] = parsePortType(xmlResult[i]);
					}
				}
				
				return tmp.length> 0 ? tmp : obj;
			}
		}
		
		
		private function parsePortType(result:Object): Object {
			
			switch(result.toLowerCase()) {
				case "any":				
					return result;				
					break;
					
				case "boolean":					
					return result.toString().toLowerCase() == "true" ? true : false;						
					break;	
								
				case "int":					
					return int(result);						
					break;
					
				case "decimal":
				case "float":
				case "double":
				case "long":				
					return Number(result);						
					break;					
					
				case "string":
				default:				
					return String(result);
			}
		}		
	
		public function get data():Object {
			return objData;
		}
	}
}
